package com.huantai.common.controller;

import com.google.gson.Gson;
import com.huantai.common.dto.BasePageResult;
import com.huantai.common.dto.BaseResponse;
import com.huantai.common.enums.ReturnCode;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

import java.util.List;

/**
 * Rest Controller 基类
 *
 * @param <T>
 * @author Ma Chao
 * @version 2019年5月22日 下午5:22:52
 */
@SuppressWarnings("rawtypes")
public class BaseRestController<T extends java.io.Serializable> {
    /**
     * 使用RestTemplate调用接口时，构造JSON对象请求
     *
     * @param request 请求参数
     * @return 封装好的请求实体对象
     */
    protected HttpEntity<String> buildJsonRequest(Object request) {
        // 设置JSON数据的请求头信息
        HttpHeaders headers = new HttpHeaders();
        MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(mediaType);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        String body = new Gson().toJson(request);
        return new HttpEntity<>(body, headers);
    }

    protected BaseResponse<T> succResponse(T result, String message) {
        BaseResponse<T> response = new BaseResponse();
        response.setCode(ReturnCode.SUCCESS.getCode());
        response.setMessage(message);
        response.setResult(result);
        return response;
    }

    protected BaseResponse<T> succResponse(T result) {
        BaseResponse<T> response = new BaseResponse<>();
        response.setCode(ReturnCode.SUCCESS.getCode());
        response.setMessage(ReturnCode.SUCCESS.getMessage());
        response.setResult(result);
        return response;
    }

    /**
     * 参数校验失败返回<code>T</code>类型的响应
     */
    protected BaseResponse<T> verifyFailed(BindingResult validResult) {
        String message = buildErrorMessage(validResult.getFieldErrors());
        BaseResponse<T> response = new BaseResponse<>();
        response.setCode(ReturnCode.VERFY_FAILED.getCode());
        response.setMessage(message);
        return response;
    }

    /**
     * 参数校验失败返回<code>BasePageResult<T></code>类型的响应
     */
    protected BaseResponse<BasePageResult<T>> verifyFailedPage(BindingResult validResult) {
        String message = buildErrorMessage(validResult.getFieldErrors());
        BaseResponse<BasePageResult<T>> response = new BaseResponse<>();
        response.setCode(ReturnCode.VERFY_FAILED.getCode());
        response.setMessage(message);
        return response;
    }

    /**
     * 熔断方法返回的响应结果
     */
    protected BaseResponse hystrixResponse() {
        BaseResponse response = new BaseResponse<>();
        response.setCode(ReturnCode.SYS_ERROR.getCode());
        response.setMessage(ReturnCode.SYS_ERROR.getMessage());
        return response;
    }

    /**
     * 拼接所有校验失败的消息
     */
    protected String buildErrorMessage(List<FieldError> errorList) {
        StringBuilder errorMsg = new StringBuilder();
        if (null != errorList && !errorList.isEmpty()) {
            for (FieldError error : errorList) {
                errorMsg.append(error.getField()).append(" : ").append(error.getDefaultMessage())
                        .append(";");
            }
        }
        errorMsg.deleteCharAt(errorMsg.length() - 1).append(".");
        return errorMsg.toString();
    }

    /**
     * 封装字节流文件
     *
     * @param fileName      文件名
     * @param contentLength 文件长度
     * @param is            字节流
     */
    protected ResponseEntity<InputStreamResource> buildStreamResopnse(String fileName,
                                                                      int contentLength, InputStreamResource is) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        return ResponseEntity.ok().headers(headers).contentLength(contentLength)
                .contentType(MediaType.parseMediaType("application/octet-stream")).body(is);
    }
}
